﻿using DH.Core;
using DH.Core.Helper;
using DH.Core.MapperHelper;
using DH.Data;
using DH.Data.ORM.EF;
using DH.Data.ORM.EF.Extensions;
using DH.Entity;
using DH.Service.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DH.Service.Domain.Role
{
   public class RoleService:BaseService<RoleEntity, string>
    {
        protected IServiceCollection _serviceCollection;
        PrivilegeService _privilegeService;
        OrganizeService _organizeService;
        public RoleService(IServiceCollection service, DbCoreUnitOfWork unitOfWork) : base(service,unitOfWork)
        {
            this._serviceCollection = service;
            this._organizeService = this._serviceCollection.BuildServiceProvider().GetService<OrganizeService>();
            this._privilegeService = this._serviceCollection.BuildServiceProvider().GetService<PrivilegeService>();
        }

        public PagedData<RoleEntity> GetList(string key, RoleQueryDto filter, Pagination page)
        {
            var roleQuery = GetAllSync() as IQueryable<RoleEntity>;
            roleQuery = roleQuery.Where(c => c.Id != Guid.Empty.ToString());
            if (!string.IsNullOrWhiteSpace(key))
            {
                roleQuery = roleQuery.Where(c => (c.Name.Contains(key)));
            }
            if (filter.status!=null)
            {
                roleQuery = roleQuery.Where(c => (c.Status==filter.status));
            }

            var tableEntityList = roleQuery.OrderBy(c => c.CreatedOn).TakePageData(page);
            return tableEntityList;
        }

        public PagedData<RoleViewModel> GetRoleList(string key, RoleQueryDto filter, Pagination page)
        {
            var roleQuery = GetAllSync() as IQueryable<RoleEntity>;
            roleQuery = roleQuery.Where(c => c.Id != Guid.Empty.ToString());
            if (!string.IsNullOrWhiteSpace(key))
            {
                roleQuery = roleQuery.Where(c => (c.Name.Contains(key)));
            }
            if (filter.status != null)
            {
                roleQuery = roleQuery.Where(c => (c.Status == filter.status));
            }

            var tableEntityList = roleQuery.OrderBy(c => c.CreatedOn).Select(c=>new RoleViewModel {
               Id=c.Id,
               Name=c.Name,
               Status=c.Status,
               Type=c.Type,
               CreatedBy=c.CreatedBy,
               CreatedOn=c.CreatedOn,
               UpdatedBy=c.UpdatedBy,
               UpdatedOn=c.UpdatedOn,
               DeletedBy=c.DeletedBy,
               DeletedOn=c.DeletedOn,
               SortIndex=c.SortIndex,
               RoleRange=c.RoleRange
            }).TakePageData(page);
            

            return tableEntityList;
        }

        public RoleEntity Add(RoleViewModel viewModel)
        {
            RoleEntity model;
            model = DHMapper.Map<RoleViewModel, RoleEntity>(viewModel);
            model.CreatedOn = DateTimeOffset.Now;
            model.UpdatedOn = DateTimeOffset.Now;
            model.SortIndex = 0;

            InsertSync(model);

            return model;


        }
        public RoleEntity Edit(RoleViewModel viewModel)
        {
            var oldObj = GetSync(viewModel.Id);
            var entityObj = DHMapper.Map<RoleViewModel, RoleEntity>(viewModel, oldObj);
            
            UpdateSync(entityObj);

            return entityObj;
        }

        public void Delete(string[] ids)
        {
            var models = GetByQuery(c => ids.Contains(c.Id));
            DeleteSync(models);
        }
        public void DeleteCascade(string[] ids) {
            var roleModels = GetByQuery(c => ids.Contains(c.Id));

            var rolePrivileges = _privilegeService.GetByQuery(c=>ids.Contains(c.SubjectId)&&c.SubjectType== PrivilegeTypeEnum.Role.ToString());

            _unitOfWork.ExecuteAndCommit(()=> {
                _repository.Delete(roleModels);

                _privilegeService.Delete(rolePrivileges);

            });
        }

        public bool EnabledRole(string id)
        {

            var userObj = GetSync(id);
            if (userObj != null)
            {
                userObj.Status = true;
                UpdateSync(userObj);
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool DisabledRole(string id)
        {
            var userObj = GetSync(id);
            if (userObj != null)
            {
                userObj.Status = false;
                UpdateSync(userObj);
                return true;
            }
            else
            {
                return false;
            }

        }
    }
}
